import { component$ } from '@builder.io/qwik';
import { type DocumentHead, routeAction$, routeLoader$, z, zod$, useNavigate } from '@builder.io/qwik-city';
import _ from 'lodash';
import { toBigint } from '~/common/bigint';
import { QPostEditor } from '~/integrations/react/post-editor';
import { getUserId, shouldAuth } from '~/server/authn';
import { createTag, searchTags } from '~/routes/create/post/server';
import { postApp } from '~/server/app/post-app';

export const useLoader = routeLoader$(async (requestEvent) => {
  const userId = getUserId(requestEvent);

  const pidStr = requestEvent.params.id;
  if (_.isEmpty(pidStr)) {
    throw requestEvent.redirect(307, '/me/post-collections');
  }

  const pid = toBigint(pidStr, () => requestEvent.redirect(307, '/me/post-collections'));
  const result = await postApp.findForUpdating(pid, userId);
  if (!result) {
    throw requestEvent.redirect(307, '/me/post-collections');
  }
  return result;
});

export const useUpdatePostAction = routeAction$(
  async (props, requestEvent) => {
    await shouldAuth(requestEvent);
    const userId = getUserId(requestEvent);
    await postApp.updatePost({
      id: BigInt(props.id),
      title: props.title,
      content: props.content,
      tagIds: props.tagIds,
      userId,
    });
  },
  zod$(
    z.object({
      id: z.string().regex(/^[1-9][0-9]?$/, { message: 'id不合法' }),
      title: z
        .string()
        .min(1, { message: '标题至少应包含一个字符。' })
        .max(200, { message: '标题不可超过200个字符。' }),
      content: z
        .string()
        .min(1, { message: '正文至少应包含一个字符。' })
        .max(20000, { message: '正文不可超过20000个字符。' }),
      tagIds: z.array(z.string().regex(/^[1-9][0-9]?$/, { message: 'id不合法' })),
    })
  )
);

export default component$(() => {
  const collectionSignal = useLoader();
  const navigate = useNavigate();
  const { post, tags } = collectionSignal.value;
  const postIdStr = post.id.toString();
  const updatePost = useUpdatePostAction();
  return (
    <div>
      <h1 class="text-xl font-bold text-kq-900 my-4">修改文章</h1>
      <QPostEditor
        client:only
        data={{ ...post, tags: tags.map((it) => ({ id: it.id, name: it.name })) }}
        onSearchTags$={async (tagName) => {
          try {
            const tags = await searchTags(tagName);
            return { ok: true, data: tags };
          } catch (e) {
            return { ok: false, error: (e as Error).message || '未知错误' };
          }
        }}
        onCreateTag$={async (tagName) => {
          try {
            const t = await createTag(tagName);
            return { ok: true, data: t };
          } catch (e) {
            return { ok: false, error: (e as Error).message || '未知错误' };
          }
        }}
        onSave$={async ({ title, content, tags }) => {
          const result = await updatePost.submit({
            id: postIdStr,
            title,
            content,
            tagIds: tags.map((it) => it.id.toString()),
          });
          console.log('result', result);
          if (result.status === 200) {
            navigate(`/posts/${postIdStr}`);
            return;
          }
          if (result.value.failed) {
            const { fieldErrors, formErrors } = result.value;
            const errorMessage = _(fieldErrors)
              .values()
              .map((it) => (_.isNil(it) ? [] : it))
              .flatten()
              .concat(formErrors)
              .first();
            console.log('errorMessage', errorMessage);
            throw new Error(errorMessage || '未知错误');
          } else {
            navigate(`/posts/${postIdStr}`);
          }
        }}
      />
    </div>
  );
});

export const head: DocumentHead = {
  title: '修改文章',
};
